<?php

abstract class JSessionNamespace
{
    /** @var Zend_Session_Namespace */
    protected static $session;

    /**
     * @return Zend_Session_Namespace
     */
    public static function factory()
    {
        $moduleName = Zend_Controller_Front::getInstance()->getRequest()->getModuleName();
        $sessionID = md5($moduleName);
        if (!Zend_Session::isStarted()) {
            Zend_Session::setId($sessionID);
        } elseif (Zend_Session::getId() != $sessionID) {
            session_commit();
            session_id($sessionID);
            session_start();
        }

        if (!isset(self::$session)) {
            self::$session = new Zend_Session_Namespace();
        }

        return self::$session;
    }
}

abstract class JSession
{
    /** @var string[] */
    protected static $special_vars = array('shoppingCart', 'user');

    /**
     * @param string $name
     * @return mixed
     * @throws Exception
     */
    public static function getVar($name)
    {
        if (in_array($name, self::$special_vars)) {
            throw new Exception("cannot get $name, you must use get $name method");
        }

        $sessionNamespace = JSessionNamespace::factory();
        return $sessionNamespace->$name;
    }

    /**
     * @param string $name
     * @param mixed $val
     * @return void
     * @throws Exception
     */
    public static function setVar($name, $val)
    {
        if (in_array($name, self::$special_vars)) {
            throw new Exception("cannot set $name, you must use set $name method");
        }

        $sessionNamespace = JSessionNamespace::factory();
        $sessionNamespace->$name = $val;
    }

    /**
     * @return ShoppingCart
     */
    public static function getShoppingCart()
    {
        $sessionNamespace = JSessionNamespace::factory();
        return $sessionNamespace->shoppingCart;
    }

    /**
     * @param ShoppingCart $shoppingCart
     * @return void
     */
    public static function setShoppingCart($shoppingCart)
    {
        $sessionNamespace = JSessionNamespace::factory();
        $sessionNamespace->shoppingCart = $shoppingCart;
    }

    /**
     * @return JUser
     */
    public static function getUser()
    {
        $sessionNamespace = JSessionNamespace::factory();
        return $sessionNamespace->user;
    }

    /**
     * @param JUser $user
     * @return void
     */
    public static function setUser($user)
    {
        $sessionNamespace = JSessionNamespace::factory();
        $sessionNamespace->user = $user;
    }
}
